package gui;

import jade.domain.FIPAAgentManagement.DFAgentDescription;
import jade.domain.FIPAAgentManagement.Property;
import jade.domain.FIPAAgentManagement.ServiceDescription;
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JList;
import javax.swing.UIManager;
import javax.swing.AbstractListModel;
import javax.swing.JTextArea;
import java.awt.Font;
import java.awt.Color;
import javax.swing.border.EtchedBorder;
import java.util.ArrayList;
import java.util.Iterator;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.ListSelectionModel;

import java.awt.Dimension;

public class ProfilerGUI extends JFrame {
	private JPanel contentPane;
	private JTextArea txtrTextArea;
	private DFAgentDescription[] providerAgents;
	private ArrayList<String> agentNames;
	private JPanel northPanel;
	private JPanel southPanel;
	private JList agentList;
	private JList servicesList;
	private JPanel agentPanel;
	private JPanel servicesPanel;

	/**
	 * Create the frame.
	 */
	public ProfilerGUI(DFAgentDescription[] agents) {
		setMaximumSize(new Dimension(300, 300));
		
		this.providerAgents = agents;
		this.agentNames = new ArrayList<String>();
		
		for(DFAgentDescription agent : providerAgents) {
			agentNames.add(agent.getName().getLocalName());
		}
		
		setTitle("Service Parameters Inspector");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 440, 307);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(new BorderLayout(0, 0));
		
		northPanel = new JPanel();
		contentPane.add(northPanel, BorderLayout.NORTH);
		
		agentPanel = new JPanel();
		agentPanel.setBackground(Color.WHITE);
		agentPanel.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
		northPanel.add(agentPanel);
		
		agentList = new JList();
		agentList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		
		// The user selected a new value (agent) in the list
		agentList.addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent arg0) {
				
				if(!arg0.getValueIsAdjusting()) {
					// Update the services according to agent selection;
					if(agentList.getSelectedIndex() != -1)
						updateServiceList(agentList.getSelectedIndex());
				}
			}
		}); 
		agentPanel.add(agentList);
		agentList.setModel(new AbstractListModel() {
			
			Object[] values = agentNames.toArray();
	
			public int getSize() {
				return values.length;
			}
			public Object getElementAt(int index) {
				return values[index];
			}
		});

		servicesPanel = new JPanel();
		servicesPanel.setBackground(Color.WHITE);
		servicesPanel.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
		northPanel.add(servicesPanel);
		
		servicesList = new JList();
		servicesList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		servicesPanel.add(servicesList);
		
		// The user selected a new value (service) in the list
		servicesList.addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent arg0) {
				
				if(!arg0.getValueIsAdjusting()) {
					// Update the information according to agent selection;
					if(servicesList.getSelectedIndex() != -1)
						updateServiceDetails(agentList.getSelectedIndex(), servicesList.getSelectedIndex());
				}
			}
		});
		
		southPanel = new JPanel();
		contentPane.add(southPanel, BorderLayout.CENTER);
		
		txtrTextArea = new JTextArea();
		txtrTextArea.setRows(4);
		txtrTextArea.setText("Select a service to receive detailed information about the required parameters.");
		southPanel.add(txtrTextArea);
		txtrTextArea.setBackground(UIManager.getColor("Button.background"));
		txtrTextArea.setFont(new Font("Tahoma", Font.PLAIN, 11));
	}
	
	private void updateServiceList(int agentIndex) {
		
		System.out.println("updateServiceList(" + agentIndex + ")");
		
		DFAgentDescription activeAgent = providerAgents[agentIndex];
		@SuppressWarnings("unchecked")
		Iterator<ServiceDescription> serviceIterator = activeAgent.getAllServices();
	
		final ArrayList<String> serviceNames = new ArrayList<String>();
		
		// As long as there are more elements to add, continue
		while(serviceIterator.hasNext()) {
			serviceNames.add(serviceIterator.next().getName());
		}
		
		// Set the model for the service list to a new list of service names
		servicesList.setModel(new AbstractListModel() {
			
			Object[] values = serviceNames.toArray();
			
			public int getSize() {
				return values.length;
			}
			public Object getElementAt(int index) {
				return values[index];
			}
		});
		
		servicesList.setPreferredSize(agentList.getSize());
		validate();
	}
	
	private void updateServiceDetails(int agentIndex, int serviceIndex) {
		System.out.println("updateServiceDetails(" + agentIndex + "," + serviceIndex + ")");
		
		DFAgentDescription activeAgent = providerAgents[agentIndex];
		@SuppressWarnings("unchecked")
		Iterator<ServiceDescription> serviceIterator = activeAgent.getAllServices();
		
		ArrayList<ServiceDescription> services = new ArrayList<ServiceDescription>();
		
		// As long as there are more elements to add, continue
		while(serviceIterator.hasNext()) {
			services.add(serviceIterator.next());
		}
		
		ServiceDescription activeService;
		
		if(serviceIndex != -1)
			activeService = services.get(serviceIndex);
		else
			activeService = services.get(0);
		
		
		Iterator<?> i = activeService.getAllProperties();
		Property p = null;
		
		if(i.hasNext())
			p = (Property) i.next();
		
		// Update the text field with detailed information about the selected service
		txtrTextArea.setText("Information about: " + activeService.getName());
		
		if(p != null)
			txtrTextArea.append("\nRequired parameters for this service: " + p.getName());
		else
			txtrTextArea.append("\nRequired parameters for this service: none");
		validate();
	}
}
